package com.jie.client.core.handler;

import com.jie.client.core.ClientApplication;
import com.jie.client.service.entity.model.*;
import com.jie.client.service.entity.vo.*;
import com.jie.common.http.constant.HttpEntityClassNameConstant;
import com.jie.common.http.constant.HttpHeaderLineNameConstant;
import com.jie.common.http.entity.request.HttpRequest;
import com.jie.common.message.entity.Message;
import com.jie.common.ssl.constant.SslConstant;
import com.jie.common.ssl.util.AesUtil;
import com.jie.common.util.JsonUtil;
import com.jie.common.util.OutputStreamUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.OutputStream;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Map;

/**
 * 客户端用于处理写的Handler类
 * @author XieZhiJie
 * @date 2022/04/22 14:52
 */
public class ClientWriteHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClientWriteHandler.class);

    /**
     * 写信息队列, 客户端通过往该队列加入要发送的信息, 以此来发送数据
     */
    private static final LinkedList<Map<String, Object>> WRITE_QUEUE = new LinkedList<>();

    /**
     * 将要发送给服务端的信息放入map中再调用这个方法
     * @param map map
     */
    public static void sendRequest(Map<String, Object> map) {
        synchronized (WRITE_QUEUE) {
            WRITE_QUEUE.add(map);
        }
    }

    public static void handleWrite(Socket socket) throws Exception {
        OutputStream outputStream = socket.getOutputStream();
        // TODO 第三部分再做这里, 因为会涉及到客户端图形化界面
        while (ClientApplication.CLIENT_STATE && !socket.isClosed()) {
            if (WRITE_QUEUE.size() <= 0) {
                continue;
            }
            Map<String, Object> sendRequestMap;
            synchronized (WRITE_QUEUE) {
                if (WRITE_QUEUE.size() > 0) {
                    sendRequestMap = WRITE_QUEUE.poll();
                } else {
                    sendRequestMap = null;
                }
            }
            if (sendRequestMap == null) {
                continue;
            }
            HttpRequest request;
            try {
                request = choice(sendRequestMap);
            } catch (Exception e) {
                request = null;
                LOGGER.error("封装请求出错!");
            }
            if (request == null) {
                continue;
            }
            Message message = new Message(request.getMessageBytes());
            message.setMessageBytes(AesUtil.addDigestAndEncrypt(message.getMessageBytes(), ClientHandler.CLIENT_SSL_MESSAGE.getAes(), SslConstant.OPEN_SSL));
            OutputStreamUtil.writeMessage(outputStream, message.getMessageBytes());
        }
    }

    /**
     * 用于将从view中发送过来的请求map封装成符合格式的request
     * @param sendRequestMap sendRequestMap
     * @return               返回封装好的request
     */
    public static HttpRequest choice(Map<String, Object> sendRequestMap) {
        String choice = (String) sendRequestMap.get("choice");
        HttpRequest request;
        switch (choice) {
            case "register":
                request = register(sendRequestMap);
                break;
            case "login":
                request = login(sendRequestMap);
                break;
            case "getUserInfo":
                request = getUserInfo(sendRequestMap);
                break;
            case "getUserList":
                request = getUserList();
                break;
            case "getOnlineUserList":
                request = getOnlineUserList();
                break;
            case "updateUserInfo":
                request = updateUserInfo(sendRequestMap);
                break;
            case "chatToOne":
                request = chatToOne(sendRequestMap);
                break;
            case "chatToOneRecords":
                request = chatToOneRecords(sendRequestMap);
                break;
            case "buildGroup":
                request = buildGroup(sendRequestMap);
                break;
            case "getGroupList":
                request = getGroupList();
                break;
            case "getUserGroupList":
                request = getUserGroupList();
                break;
            case "updateGroupName":
                request = updateGroupName(sendRequestMap);
                break;
            case "joinGroup":
                request = joinGroup(sendRequestMap);
                break;
            case "signOutGroup":
                request = signOutGroup(sendRequestMap);
                break;
            case "getGroupUserList":
                request = getGroupUserList(sendRequestMap);
                break;
            case "chatToGroup":
                request = chatToGroup(sendRequestMap);
                break;
            case "chatToGroupRecords":
                request = chatToGroupRecords(sendRequestMap);
                break;
            case "addFollow":
                request = addFollow(sendRequestMap);
                break;
            case "getFollowUserList":
                request = getFollowUserList();
                break;
            case "getOnlineFollowUserList":
                request = getOnlineFollowUserList();
                break;
            case "cancelFollow":
                request = cancelFollow(sendRequestMap);
                break;
            case "updateFollow":
                request = updateFollow(sendRequestMap);
                break;
            case "getNotFollowUserList":
                request = getNotFollowUserList();
                break;
            default:
                request = getAllUser();
                break;
        }
        return request;
    }

    public static HttpRequest register(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/register");
        // 需要用户帐号和密码和用户名
        User user = (User) sendRequestMap.get("user");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.setEntity(JsonUtil.toJson(user));
        return httpRequest;
    }

    public static HttpRequest login(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/login");
        // 需要用户帐号和密码
        User user = (User) sendRequestMap.get("user");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.setEntity(JsonUtil.toJson(user));
        return httpRequest;
    }

    public static HttpRequest getUserInfo(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/get/info");
        // 带上cookie
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        // 输入用户id
        httpRequest.setEntity(sendRequestMap.get("userId"));
        return httpRequest;
    }

    public static HttpRequest getUserList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/get/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        UserQueryVo userQueryVo = new UserQueryVo();
        userQueryVo.setCurrent(1);
        userQueryVo.setLimit(100);
        httpRequest.setEntity(JsonUtil.toJson(userQueryVo));
        return httpRequest;
    }

    public static HttpRequest getOnlineUserList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/get/online/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        return httpRequest;
    }

    public static HttpRequest updateUserInfo(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/update");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        // 需要用户名和用户密码
        UserUpdateVo userUpdateVo = (UserUpdateVo) sendRequestMap.get("userUpdateVo");
        httpRequest.setEntity(JsonUtil.toJson(userUpdateVo));
        return httpRequest;
    }

    public static HttpRequest chatToOne(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("jie/chat/single-chat/chat");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        // 需要传入接收方用户id与发送信息
        SingleChat singleChat = (SingleChat) sendRequestMap.get("singleChat");
        singleChat.setSendUserId(Integer.parseInt(ClientApplication.COOKIE));
        String sendMessage = singleChat.getChatMessage();
        if ("".equals(sendMessage)) {
            System.out.println("发送信息不能为空! 发送失败!");
            return null;
        }
        singleChat.setChatMessage(sendMessage);
        httpRequest.setEntity(JsonUtil.toJson(singleChat));
        return httpRequest;
    }

    public static HttpRequest chatToOneRecords(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("jie/chat/single-chat/records");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        SingleChatQueryVo singleChatQueryVo = new SingleChatQueryVo();
        singleChatQueryVo.setTargetUserId((Integer) sendRequestMap.get("targetUserId"));
        singleChatQueryVo.setCurrent(1);
        singleChatQueryVo.setLimit(200);
        httpRequest.setEntity(JsonUtil.toJson(singleChatQueryVo));
        return httpRequest;
    }

    public static HttpRequest buildGroup(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/build");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        // 需要输入组名(直接输入组名即可)
        Group group = new Group();
        group.setGroupName((String) sendRequestMap.get("groupName"));
        httpRequest.setEntity(JsonUtil.toJson(group));
        return httpRequest;
    }

    public static HttpRequest getGroupList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/get/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        GroupQueryVo groupQueryVo = new GroupQueryVo();
        groupQueryVo.setCurrent(1);
        groupQueryVo.setLimit(300);
        httpRequest.setEntity(JsonUtil.toJson(groupQueryVo));
        return httpRequest;
    }

    public static HttpRequest getUserGroupList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/get/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        GroupQueryVo groupQueryVo = new GroupQueryVo();
        groupQueryVo.setCurrent(1);
        groupQueryVo.setLimit(400);
        httpRequest.setEntity(JsonUtil.toJson(groupQueryVo));
        return httpRequest;
    }

    public static HttpRequest updateGroupName(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/update/group/name");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        // 需要输入组id与组名
        GroupUpdateVo groupUpdateVo = (GroupUpdateVo) sendRequestMap.get("groupUpdateVo");
        httpRequest.setEntity(JsonUtil.toJson(groupUpdateVo));
        return httpRequest;
    }

    public static HttpRequest joinGroup(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/join/group");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        // 组id
        httpRequest.setEntity(sendRequestMap.get("groupId"));
        return httpRequest;
    }

    public static HttpRequest signOutGroup(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/sign/out");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        // 组id
        httpRequest.setEntity(sendRequestMap.get("groupId"));
        return httpRequest;
    }

    public static HttpRequest getGroupUserList(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group/get/group/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        // 组id
        String groupId = String.valueOf(sendRequestMap.get("groupId"));
        httpRequest.setEntity(groupId);
        return httpRequest;
    }

    public static HttpRequest chatToGroup(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group-chat/chat");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        GroupChat groupChat = new GroupChat();
        groupChat.setSendUserId(Integer.parseInt(ClientApplication.COOKIE));
        groupChat.setGroupId((Integer) sendRequestMap.get("groupId"));
        String sendMessage = (String) sendRequestMap.get("sendMessage");
        if ("".equals(sendMessage.trim())) {
            System.out.println("发送信息不能为空! 发送失败!");
            return null;
        }
        groupChat.setChatMessage(sendMessage.trim());
        httpRequest.setEntity(JsonUtil.toJson(groupChat));
        return httpRequest;
    }

    public static HttpRequest chatToGroupRecords(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/group-chat/records");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        GroupChatQueryVo groupChatQueryVo = new GroupChatQueryVo();
        // 组id
        groupChatQueryVo.setTargetGroupId((Integer) sendRequestMap.get("targetGroupId"));
        groupChatQueryVo.setCurrent(1);
        groupChatQueryVo.setLimit(500);
        httpRequest.setEntity(JsonUtil.toJson(groupChatQueryVo));
        return httpRequest;
    }

    public static HttpRequest addFollow(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/follow/add");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        Follow follow = new Follow();
        // 需要用户id和备注
        follow.setOtherUserId((Integer) sendRequestMap.get("otherUserId"));
        follow.setRemark((String) sendRequestMap.get("remark"));
        httpRequest.setEntity(JsonUtil.toJson(follow));
        return httpRequest;
    }

    public static HttpRequest getFollowUserList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/follow/get/follow/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        FollowQueryVo followQueryVo = new FollowQueryVo();
        followQueryVo.setCurrent(1);
        followQueryVo.setLimit(600);
        httpRequest.setEntity(JsonUtil.toJson(followQueryVo));
        return httpRequest;
    }

    public static HttpRequest getOnlineFollowUserList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/follow/get/online/follow/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        return httpRequest;
    }

    public static HttpRequest cancelFollow(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/follow/cancel");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        // 输入要删除的关注的用户id
        httpRequest.setEntity(sendRequestMap.get("userId"));
        return httpRequest;
    }

    public static HttpRequest updateFollow(Map<String, Object> sendRequestMap) {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/follow/update");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        Follow follow = new Follow();
        // 用户id和备注
        follow.setOtherUserId((Integer) sendRequestMap.get("otherUserId"));
        follow.setRemark((String) sendRequestMap.get("remark"));
        httpRequest.setEntity(JsonUtil.toJson(follow));
        return httpRequest;
    }

    public static HttpRequest getNotFollowUserList() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/follow/get/not/follow/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        return httpRequest;
    }

    public static HttpRequest getAllUser() {
        HttpRequest httpRequest = new HttpRequest("/jie/chat/user/get/user/list");
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.COOKIE, ClientApplication.COOKIE);
        httpRequest.addOneHeaderLine(HttpHeaderLineNameConstant.ENTITY_DATA_CLASS_NAME, HttpEntityClassNameConstant.STRING_CLASS_NAME);
        UserQueryVo userQueryVo = new UserQueryVo();
        userQueryVo.setCurrent(1);
        userQueryVo.setLimit(700);
        httpRequest.setEntity(JsonUtil.toJson(userQueryVo));
        return httpRequest;
    }

}
